<!--
 * @Author: 周艳凯 484894717@qq.com
 * @Date: 2025-03-17 15:35:05
 * @LastEditors: 周艳凯 484894717@qq.com
 * @LastEditTime: 2025-04-08 18:19:46
 * @FilePath: \BusStopBoard.Webd:\360MoveData\Users\75041\Desktop\uniapp框架\my-project\src\pages\loading\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
    <div class="load-contain">
        <div class="loading-wave">
            <div class="loading-bar"></div>
            <div class="loading-bar"></div>
            <div class="loading-bar"></div>
            <div class="loading-bar"></div>
        </div>
    </div>
</template>

<script>
import { getnodelistbydevsn, getStationConfig, getitemlistbydevsn } from '@/api/common/user/user';
// import websocketUtils from '../index/websock'
const imageExtensions = new Set(['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']);
const videoExtensions = new Set(['mp4', 'avi', 'mov', 'mkv', 'flv', 'webm']);

function getExtension(filename) {
    const match = filename.match(/\.([^.]+)$/);
    return match ? match[1].toLowerCase() : null;
}

export default {
    data() {
        return {
            filePath: '', // 保存文件路径
            fileName: '',
            intervalId:null,
        }
    },
    created() {
        console.log(this.$store, '我挂载了')
        this.init()
    },
    // 生命周期管理
    beforeDestroy() {
        // 组件销毁时强制清除定时器
        if (this.intervalId !== null) {
            clearInterval(this.intervalId);
            this.intervalId = null;
            console.log('我销毁loading页面了老弟')
        }
    },
    methods: {
        async init() {
            const flog = this.$store.state.isFirst
            if (flog) {
                uni.reLaunch({ url: '/pages/mpdel/index' });
                return
            }
            this.initConfig()
            // this.initText()
            // 获取图片配置
            this.initImg()
            // 获取线路配置
            await this.initLine()
            // 获取图片         
            this.intervalId = setTimeout(() => {
                uni.reLaunch({ url: '/pages/index/index' });
            }, 2000);
        },
        // 配置文件
        async initConfig() {
            try {
                await getStationConfig().then((res) => {
                    this.$store.commit('changeStationConfig', res.data.result)
                });
            } catch (error) {
                console.log(error, '我配置文件出错了')
            }
        },
        // 获取线路配置
        async initLine() {
            try {
                await getnodelistbydevsn({
                    DevSN: this.$store.state.androidId
                }).then((res) => {
                    // console.log(res.data.result, '我无语了');
                    const initialData = Array.isArray(res.data?.result) ? res.data.result : [];
                    // this.lineNode = res.data.result
                    const promotionSlogans = Array.isArray(this.$store.state.StationConfig.promotionSlogan)
                        ? this.$store.state.StationConfig.promotionSlogan
                        : [];

                    const usedIndices = new Set() // 使用Set记录已用索引
                    let allSloganIndices = []    // 记录所有可用索引

                    // 初始化索引池（仅在文案变化时重置）
                    if (allSloganIndices.length !== promotionSlogans.length) {
                        allSloganIndices = Array.from({ length: promotionSlogans.length }, (_, i) => i);
                        usedIndices.clear();
                    }

                    // 计算需要生成的数量
                    const requiredCount = Math.max(4 - initialData.length, 0);
                    // 生成不重复项
                    const fillerItems = [];
                    for (let i = 0; i < requiredCount; i++) {
                        // 获取可用索引（排除已用）
                        let availableIndices = allSloganIndices.filter(
                            idx => !usedIndices.has(idx)
                        );
                        // 当可用索引不足时重置
                        if (availableIndices.length === 0 && promotionSlogans.length > 0) {
                            usedIndices.clear();
                            availableIndices = [...allSloganIndices];
                        }
                        // 随机选择（带默认值处理）
                        const newIndex = availableIndices.length > 0
                            ? availableIndices[Math.floor(Math.random() * availableIndices.length)]
                            : -1;

                        const slogan = newIndex !== -1
                            ? promotionSlogans[newIndex]
                            : "";

                        fillerItems.push({
                            type: 'text',
                            name: slogan
                        });
                        // 记录已用索引（有效索引时才记录）
                        if (newIndex !== -1) usedIndices.add(newIndex);
                    }
                    console.error([...initialData, ...fillerItems], '我是限流数据')
                    this.$store.commit('changelineNode', [...initialData, ...fillerItems])
                });
            }
            catch (error) {
                console.error('Error fetching line data:', error);
                // console.log(res.data.result, '我无语了');
                const initialData = [];
                // this.lineNode = res.data.result
                const promotionSlogans = Array.isArray(this.$store.state.StationConfig.promotionSlogan)
                    ? this.$store.state.StationConfig.promotionSlogan
                    : [];

                const usedIndices = new Set() // 使用Set记录已用索引
                let allSloganIndices = []    // 记录所有可用索引

                // 初始化索引池（仅在文案变化时重置）
                if (allSloganIndices.length !== promotionSlogans.length) {
                    allSloganIndices = Array.from({ length: promotionSlogans.length }, (_, i) => i);
                    usedIndices.clear();
                }

                // 计算需要生成的数量
                const requiredCount = Math.max(4 - initialData.length, 0);
                // 生成不重复项
                const fillerItems = [];
                for (let i = 0; i < requiredCount; i++) {
                    // 获取可用索引（排除已用）
                    let availableIndices = allSloganIndices.filter(
                        idx => !usedIndices.has(idx)
                    );
                    // 当可用索引不足时重置
                    if (availableIndices.length === 0 && promotionSlogans.length > 0) {
                        usedIndices.clear();
                        availableIndices = [...allSloganIndices];
                    }
                    // 随机选择（带默认值处理）
                    const newIndex = availableIndices.length > 0
                        ? availableIndices[Math.floor(Math.random() * availableIndices.length)]
                        : -1;

                    const slogan = newIndex !== -1
                        ? promotionSlogans[newIndex]
                        : "";

                    fillerItems.push({
                        type: 'text',
                        name: slogan
                    });
                    // 记录已用索引（有效索引时才记录）
                    if (newIndex !== -1) usedIndices.add(newIndex);
                }
                console.error([...initialData, ...fillerItems], '我是限流数据')
                this.$store.commit('changelineNode', [...initialData, ...fillerItems])
                console.warn('我进入到报错里面了')
            }
        },
        // 加载图片资源
        async initImg() {
            console.log(this.$store.state.androidId,'我循环调用了轮播图')
            // 获取轮播图
            await getitemlistbydevsn({
                DevSN: this.$store.state.androidId,
            })
                .then(async (res) => {
                    console.warn(res, '我是循环轮播数据')
                    const imageList = this.$store.getters.getswiperList

                    // 合并 video 和 picture 数组
                    let combinedMedia = [
                        ...(res.data.result.picture || []),
                        ...(res.data.result.video || [])];
                    combinedMedia = combinedMedia.map(item => {
                        item.fileUrl = item.content
                        return item
                    })

                    this.$store.commit('changetextArray', res.data.result?.text || [])
                    // 获取本地存储的图片
                    const flog = this.isSameNames(imageList, combinedMedia)
                    // // 如果是true代表已经不需要更新 反之需要更新
                    // console.log('我要开始更新了')
                    if (flog) {
                        console.log('不需要更新');
                    } else {
                        console.log('我要更新')
                        // #ifdef APP-PLUS
                        const results = await this.getSavedFileList()
                        this.$store.commit('changeSwiper', [])
                        console.log('清理成功我先执行', results)
                        // #endif                     
                        if (!res.data.result) {
                            return this.$store.commit('changeSwiper', [])
                        }
                        const downloadTasks = combinedMedia.map(async (item, index) => {
                            // 获取文件扩展名
                            const extension = getExtension(item.fileUrl);
                            if (!extension) return false;
                            const params = {
                                type: '',
                                src: '',
                                id: index,
                                fileUrl: item.fileUrl
                            };
                            if (imageExtensions.has(extension)) {
                                params.type = 'image';
                            } else if (videoExtensions.has(extension)) {
                                params.type = 'video';
                            }
                            const url = `${this.$store.state.apiUrl}/${item.fileUrl}`;
                            console.log(url, '我是图片地址')

                            // #ifdef APP-PLUS
                            const savedPath = await this.downloadAndSave(url);
                            // #endif 
                            // #ifdef H5
                            const savedPath = url
                            // #endif 
                            params.src = savedPath;
                            return params;
                        });
                        // 4. 过滤失败项并存储
                        const result = await Promise.all(downloadTasks)
                        console.log(result, '我是更新后的轮播图地地址')
                        this.$store.commit('changeSwiper', result)
                    }
                })
                .catch((error) => {
                    console.log(error, '我是轮播图失败了');
                    // uni.showToast({
                    //     title: '轮播图更新失败' + error,
                    //     icon: 'none',
                    //     duration: 10000,
                    // });
                });
        },
        isSameNames(arr1, arr2) {
            // 简化 null/undefined 检查
            if (arr1 == null || arr2 == null) return false;
            // 确保类型为数组
            if (!Array.isArray(arr1) || !Array.isArray(arr2)) return false;
            // 长度不等直接返回
            if (arr1.length !== arr2.length) return false;
            // 提取并排序 fileUrl 数组
            const getSortedUrls = (arr) => arr.map(item => item.fileUrl).sort();

            const names1 = getSortedUrls(arr1);
            const names2 = getSortedUrls(arr2);

            // 逐元素比较提升性能
            return names1.every((value, index) => value === names2[index]);
        },
        /**
         * 获取本地保存的文件列表
         * @returns {Promise<Array>} 包含文件信息的数组
         */
        async getSavedFileList() {
            try {
                // 1. Promise 化获取文件列表
                const fileRes = await new Promise((resolve) => {
                    uni.getSavedFileList({
                        success: resolve,
                        fail: err => resolve({ errMsg: err.errMsg }) // 错误也转为 resolve
                    });
                })
                // 2. 处理获取列表失败或空列表的情况
                if (fileRes.errMsg !== 'getSavedFileList:ok') {
                    return { success: false, error: '获取文件列表失败', detail: fileRes };
                }
                if (!fileRes.fileList?.length) {
                    return { success: true, message: '无缓存文件' };
                }
                // 3. 并行删除所有文件（兼容失败）
                const deleteResults = await Promise.all(
                    fileRes.fileList.map(file =>
                        new Promise(resolve => {
                            uni.removeSavedFile({
                                filePath: file.filePath,
                                complete: (res) => {
                                    // 统一返回结构：成功时 error 为 null
                                    resolve(res.errMsg === 'removeSavedFile:ok' ?
                                        { success: true, filePath: file.filePath } :
                                        { success: false, filePath: file.filePath, error: res }
                                    );
                                }
                            });
                        })
                    )
                );
                // 4. 统计操作结果
                const errors = deleteResults.filter(v => !v.success);
                return {
                    success: errors.length === 0,
                    deletedCount: deleteResults.length - errors.length,
                    errors: errors,
                    message: errors.length ?
                        `删除了 ${deleteResults.length - errors.length} 个文件，${errors.length} 个失败` :
                        '所有文件删除成功'
                };
            } catch {
                return {
                    success: false,
                    error: '未知异常',
                    detail: error
                };
            }
        },
        // 下载并保存文件
        async downloadAndSave(url) {
            try {
                // 下载阶段（使用await保证顺序执行）
                const { tempFilePath } = await new Promise((resolve, reject) => {
                    uni.downloadFile({
                        url,
                        success: (res) => {
                            if (res.statusCode === 200) {
                                resolve(res)
                            } else {
                                reject(new Error(`下载失败，状态码：${res.statusCode}`))
                            }
                        },
                        fail: reject
                    })
                })

                // 持久化存储阶段
                const { savedFilePath } = await new Promise((resolve, reject) => {
                    uni.saveFile({
                        tempFilePath,
                        success: resolve,
                        fail: reject
                    })
                })

                return savedFilePath

            } catch (error) {
                // 统一错误处理（不会向上抛出异常）
                console.error('[文件操作]', error.message)
                return null // 返回null而不是undefined更符合规范
            }
        },
        // initWebsock() {
        //     const socketWBObj = new websocketUtils(`${process.env.VUE_APP_API_URL}/hubs/device?DevSn=${this.$store.state.androidId}`, 30)
        //     socketWBObj.exportMessage(res => {
        //         try {
        //             var msg = res.data.replace(String.fromCharCode(0x1e), ""); //替换消息结束符
        //             let msgData = JSON.parse(msg);
        //             // this.$store.commit('changePushText', 121);
        //             console.log(msgData.type, msgData.target, msgData.type === 1 && msgData.target == "ReceiveMessage", '我进入判断了')
        //             //接收指定消息（这里为服务端得ReceiveMessage得消息，msgData.type === 1 为固定值表示调用客户端的一个方法）
        //             if (msgData.type === 1 && msgData.target == "ReceiveMessage") {
        //                 if (msgData.arguments[0].lineIds == 'Text' || msgData.arguments[0].lineIds == 'Clear') {
        //                     this.$store.commit('changePushText', msgData.arguments[0]);
        //                     return
        //                 }
        //                 this.$store.commit('SET_receiveUserName', msgData.arguments[0]);
        //             }
        //         } catch (error) {
        //             console.log(error, '我web出错了');
        //         }
        //     })
        // }
    }
}

</script>

<style lang="scss" scoped>
.load-contain {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
}

.loading-wave {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    width: 300px;
    height: 60px;
}

.loading-bar {
    width: 20px;
    height: 10px;
    margin: 0 5px;
    background-color: #3498db;
    border-radius: 5px;
    animation: loading-wave-animation 1s ease-in-out infinite;
}

.loading-bar:nth-child(2) {
    animation-delay: 0.1s;
}

.loading-bar:nth-child(3) {
    animation-delay: 0.2s;
}

.loading-bar:nth-child(4) {
    animation-delay: 0.3s;
}

@keyframes loading-wave-animation {
    0% {
        height: 10px;
    }

    50% {
        height: 50px;
    }

    100% {
        height: 10px;
    }
}
</style>
